package com.aps.algorithm.heuristic.genetic.model;

import java.util.List;

import com.aps.algorithm.utils.MathUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author nbZhuozh
 * @Date 2025-09-08  14:28
 *
 * GA_ALGORITHM -抽象初始化种群
 *
 * CLASS JOB : <Chromosome,R>  Chromosome:染色体  R：基因
 * - 定义所需 参数配置项
 * - 定义所需 业务基础数据
 *
 * - 初始化种群标准化流程
 *  - 生成基因序列
 *  - 计算全排列体量
 *  - 生成计算策略
 *  - 生成种群，按规则排序算法 （默认按照工序的 顺序【硬约束】 进行排序）打乱的结果输出的衡量标准
 *  - 构造返回结果
 **/
@Slf4j
public abstract class AbstractInitializePopulation<R extends Gene> {

    //种群大小
    public long _population_size;

    //全排列长度
    public long _max_permutation_threshold;

    //染色体
    private List<Chromosome<R>> _population;

    //计算策略
    private InitialPopulationType initialPopulationType;

    protected AbstractInitializePopulation(long population_size, long max_permutation_threshold) {
        _population_size = population_size;
        _max_permutation_threshold = max_permutation_threshold;
    }
    protected AbstractInitializePopulation() {
        //默认种群大小、可执行全排列的长度
        this(50, 5000);
    }

    public InitialPopulationData doInitializePopulation() {
        log.info("Initialize population start ===================================================================");
        //初始化基因序列
        List<R> geneSequence = generateGeneSequence();
        log.info("生成基因序列，基因数量：{}", geneSequence.size());

        //确定初始化策略
        this.initialPopulationType = determineStrategy(generateGeneSequence());
        log.info("选择初始化策略：{}", initialPopulationType);

        //生成染色体种群
        this._population = generatePopulation(geneSequence, initialPopulationType);
        log.info("生成种群完成，染色体数量：{}", _population.size());
        log.info("Initialize population end ===================================================================");
        //构建返回结果
        return this.builder();
    }

    /**
     * 初始化基因序列
     * @return
     */
    public abstract List<R> generateGeneSequence();

    /**
     * 初始化策略
     */
    public InitialPopulationType determineStrategy(List<R> genes){
        long totalPermutations = MathUtils.calFactorial(genes.size());
        log.info("基因序列全排列数量：{}", totalPermutations);
        if (totalPermutations <= _max_permutation_threshold) {
            return InitialPopulationType.ALL;
        } else {
            return InitialPopulationType.PART;
        }
    }

    /**
     * 生成染色体种群
     */
    public abstract List<Chromosome<R>> generatePopulation(List<R> genes, InitialPopulationType strategy);


    /**
     * 构造种群结果
     * @return
     */
    private InitialPopulationData builder(){
        return new InitialPopulationData(this._population,this._population.size(),this.initialPopulationType);
    }



    /**
     * 初始化种群 出参结构
     */
    @Data
    public class InitialPopulationData {
        //染色体集合
        private List<Chromosome<R>> chromosomeList;
        //种群大小
        private int populationSize;
        //遗传规则 ： 全排列 or 部分
        private InitialPopulationType initialPopulationType;

        public InitialPopulationData(List<Chromosome<R>> chromosomeList, int populationSize, InitialPopulationType initialPopulationType) {
            this.chromosomeList = chromosomeList;
            this.populationSize = populationSize;
            this.initialPopulationType = initialPopulationType;
        }
    }


    /**
     * 初始化种群类型枚举
     */
    public enum InitialPopulationType {
        ALL, //初始化种群的结果为全排列
        PART //初始化种群的结果为部分（需要 继续 交叉 + 变异）
    }


}
